/**
 * 
 */
package appStarshipPushups.client.form;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.SwingConstants;

import appStarshipPushups.client.model.Connection;
import appStarshipPushups.client.model.ConnectionException;
import appStarshipPushups.common.Protocole;
import appStarshipPushups.common.util.layout.SpringUtilities;

/**
 * Cette classe représente la boîte de dialogue de connexion du joueur.
 * @author Adam Labranche
 */
public class LoginWindow extends JDialog implements ActionListener
{
	public static final long serialVersionUID = 1L;
	// L'adresse IP par défaut.
	private static final String LOCALHOST_IP = "127.0.0.1";
	// Le titre de la fenêtre.
	private static final String TITLE = "Connexion";
	
	// Les couleurs de la fenêtre.
	private static final Color COLOR_BG = Color.black;
	private static final Color COLOR_FG = Color.white;
	
	// Les constantes des commandes d'action.
	private static final String ACT_OK = "ok";
	private static final String ACT_CANCEL = "cancel";
	
	// Les textes des boutons.
	private static final String CMD_OK = "OK";
	private static final String CMD_CANCEL = "Cancel";
	
	// Les textes des étiquettes.
	private static final String LBL_USR_NAME = "Nom d'utilisateur : ";
	private static final String LBL_PSWD = "Mot de passe : ";
	private static final String LBL_IP = "Adresse IP du serveur : ";
	private static final String LBL_PORT = "Port du serveur : ";
	
	// Les messages d'erreur.
	private static final String PSWD_EMPTY = "Vous devez entrer un mot de passe.";
	private static final String USR_NAME_EMPTY = "Vous devez entrer un nom d'utilisateur";
	private static final String IP_EMPTY = "Vous devez entrer l'adresse IP du serveur.";
	private static final String PSWD_EMPTY_TITLE = "Mot de passe manquant";
	private static final String USR_NAME_EMPTY_TITLE = "Nom d'utilisateur manquant";
	private static final String IP_EMPTY_TITLE = "Adresse IP manquant";
	private static final String IP_INVALID = "Veuillez entrer une adresse IP valide.";
	private static final String IP_INVALID_TITLE = "Adresse IP invalide";
	
	// La taille masximale du mot de passe.
	private static final int MAX_LENGTH = 25;
	
	/**
	 * Ce membre représente la boîte de texte d'entrée du nom d'utilisateur.
	 */
	private JTextField txtUsrName = new JTextField();
	/**
	 * Ce membre représente la boîte de texte d'entrée du mot de passe.
	 */
	private JPasswordField txtPswd = new JPasswordField(LoginWindow.MAX_LENGTH);
	/**
	 * Ce membre représente la boîte de texte d'entrée de l'adresse IP du 
	 * serveur.
	 */
	private JTextField txtIP = new JTextField(LoginWindow.LOCALHOST_IP);
	/**
	 * Ce membre représente le bouton de confirmation de l'information entrée.
	 */
	private JButton cmdOk = new JButton(LoginWindow.CMD_OK);
	/**
	 * Ce membre représente le bouton d'annulation de l'information entrée.
	 */
	private JButton cmdCancel = new JButton(LoginWindow.CMD_CANCEL);
	/**
	 * Ce membre représente une étiquette décrivant le txtUsrName.
	 */
	private JLabel lblUsrName = null;
	/**
	 * Ce membre représente une étiquette décrivant le txtPswd.
	 */
	private JLabel lblPswd = null;
	/**
	 * Ce membre représente une étiquette décrivant le txtIP.
	 */
	private JLabel lblIP = null;
	/**
	 * Ce membre représente une étiquette décrivant le txtPort.
	 */
	private JLabel lblPort = null;
	/**
	 * Ce membre représente la boîte de texte d'entrée du port du serveur.
	 */
	private JTextField txtPort = new JTextField(Integer.toString(Protocole.LISTENING_PORT));
	
	
	/**
	 * C'est le constructeur par défaut.
	 */
	public LoginWindow() 
	{
		super();
		this.init();
	}
	
	/**
	 * Cette fonction initialise l'interface de la fenêtre.
	 */
	private void init()
	{
		this.setTitle(LoginWindow.TITLE);
		this.getContentPane().setLayout(new BoxLayout(this.getContentPane(),
				BoxLayout.Y_AXIS));
		this.setResizable(false);
		this.setBackground(LoginWindow.COLOR_BG);
		this.getContentPane().setBackground(LoginWindow.COLOR_BG);
		this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		
		// On fait la mise en forme du panneau contenant les entrées
		// d'information de la connexion au serveur.
		JPanel panLogin = new JPanel();
		panLogin.setLayout(new SpringLayout());
		
		this.lblUsrName = new JLabel(LoginWindow.LBL_USR_NAME,
				SwingConstants.TRAILING);
		this.lblUsrName.setForeground(LoginWindow.COLOR_FG);
		panLogin.add(this.lblUsrName);
		this.lblUsrName.setLabelFor(this.txtUsrName);
		panLogin.add(this.txtUsrName);
		this.lblPswd = new JLabel(LoginWindow.LBL_PSWD, 
				SwingConstants.TRAILING);
		this.lblPswd.setForeground(LoginWindow.COLOR_FG);
		panLogin.add(this.lblPswd);
		this.lblPswd.setLabelFor(this.txtPswd);
		panLogin.add(this.txtPswd);
		this.lblIP = new JLabel(LoginWindow.LBL_IP, SwingConstants.TRAILING);
		this.lblIP.setForeground(LoginWindow.COLOR_FG);
		panLogin.add(this.lblIP);
		this.lblIP.setLabelFor(this.txtIP);
		panLogin.add(this.txtIP);
		
		this.lblPort = new JLabel(LoginWindow.LBL_PORT
				, SwingConstants.TRAILING);
		this.lblPort.setForeground(LoginWindow.COLOR_FG);
		panLogin.add(this.lblPort);
		this.lblPort.setLabelFor(this.txtPort);
		panLogin.add(this.txtPort);
		
		panLogin.setAlignmentX(CENTER_ALIGNMENT);
		panLogin.setOpaque(false);
		this.getContentPane().add(panLogin);
		
		// On fait la mise en forme des boutons de confirmation.
		JPanel panConfirmation = new JPanel();
		panConfirmation.setLayout(new FlowLayout(FlowLayout.CENTER));
		panConfirmation.setOpaque(false);
		
		this.cmdOk.setActionCommand(LoginWindow.ACT_OK);
		this.cmdOk.addActionListener(this);
		this.cmdOk.setAlignmentX(CENTER_ALIGNMENT);
		this.cmdOk.setOpaque(false);
		this.getRootPane().setDefaultButton(this.cmdOk);
		panConfirmation.add(this.cmdOk);		
		
		this.cmdCancel.setActionCommand(LoginWindow.ACT_CANCEL);
		this.cmdCancel.addActionListener(this);
		this.cmdCancel.setAlignmentX(CENTER_ALIGNMENT);
		this.cmdCancel.setOpaque(false);
		panConfirmation.add(this.cmdCancel);
		
		this.getContentPane().add(panConfirmation);
		
		// On met en place correctement les composantes de panLogin.
		SpringUtilities.makeCompactGrid(panLogin, 4, 2, 6, 6, 6, 6);
		
		this.pack();
		
		// On centre la fenêtre dans l'écran de l'utilisateur.
		this.setLocation((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - this.getWidth() / 2),
				(int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - this.getHeight() / 2));
		
		this.setModalityType(ModalityType.APPLICATION_MODAL);
	}
	
	/**
	 * Cette fonction permet de vérifier si tous les champs sont remplis et
	 * envoie l'information entrée au serveur pour tenter de se connecter.
	 */
	private void login()
	{
		if(this.txtUsrName.getText().length() == 0)
		{
			JOptionPane.showMessageDialog(this, LoginWindow.USR_NAME_EMPTY, LoginWindow.USR_NAME_EMPTY_TITLE, JOptionPane.OK_OPTION);
			this.txtPswd.setText("");
		}
		else if(this.txtPswd.getPassword().length == 0)
		{
			JOptionPane.showMessageDialog(this, LoginWindow.PSWD_EMPTY, LoginWindow.PSWD_EMPTY_TITLE, JOptionPane.OK_OPTION);
			this.txtPswd.setText("");
		}
		else if(this.txtIP.getText().length() == 0)
		{
			JOptionPane.showMessageDialog(this, LoginWindow.IP_EMPTY, LoginWindow.IP_EMPTY_TITLE, JOptionPane.OK_OPTION);
			this.txtPswd.setText("");
		}
		else
		{
			String goodIP = Connection.ipValidation(this.txtIP.getText());
			if(goodIP == "")
			{
				JOptionPane.showMessageDialog(this, LoginWindow.IP_INVALID, LoginWindow.IP_INVALID_TITLE, JOptionPane.OK_OPTION);
				this.txtPswd.setText("");
			}
			else
			{
				// Les informations sont prêtes!
				this.sendInfo(this.txtUsrName.getText(), new String(this.txtPswd.getPassword()), goodIP, Integer.parseInt(this.txtPort.getText()));
				this.dispose();
			}
		}
	}
	
	/**
	 * Cette fonction envoye l'information de connexion du joueur.
	 * @param usrName Le nom d'utilisateur
	 * @param pswd Le mot de passe
	 * @param ip L'adresse IP
	 */
	private void sendInfo(String usrName, String pswd, String ip, int port)
	{
		System.out.println(ip);
		try
		{
			Connection.getInstance().startConnection(ip, port);
			Connection.getInstance().sendMsg(Protocole.FUNCTION_JOIN
					+ Protocole.SEPARATOR + usrName + Protocole.SEPARATOR 
					+ pswd);
		}
		catch(ConnectionException e)
		{
			System.err.println(e.getMessage());
		}
	}
	
    /**
     * Appelée lorsqu'une action se produit.
     */
    public void actionPerformed(ActionEvent e)
    {
    	String actCmd = e.getActionCommand();
    	if(actCmd.equals(LoginWindow.ACT_OK))
    	{
    		this.login();
    	}
    	else if(actCmd.equals(LoginWindow.ACT_CANCEL))
    	{
    		this.dispose();
    	}
    }
}
